package ink.xiaobaibai.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import ink.xiaobaibai.autoConfig.role.DefaultRole;
import ink.xiaobaibai.autoConfig.roleResources.ResourcesRoleMapping;
import ink.xiaobaibai.bo.AddUser;
import ink.xiaobaibai.bo.UpdateUser;
import ink.xiaobaibai.common.MyRole;
import ink.xiaobaibai.controller.AdditionalController;
import ink.xiaobaibai.entity.*;
import ink.xiaobaibai.response.ResponseFormat;
import ink.xiaobaibai.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 管理员人员接口
 * @author: 小白白
 * @create: 2021-06-08
 **/

@RestController
@RequestMapping("/security/user")
@Slf4j
@CrossOrigin
@Api(tags = "后台用户接口")
@ResourcesRoleMapping(resourceName = "用户控制-用户接口", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_USER})
public class AdminController {

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private IOzoneDeviceService ozoneDeviceService;

    @Autowired
    private IOxygenDeviceService oxygenDeviceService;

    @Autowired
    private IMonthlyfeeDeviceService monthlyfeeDeviceService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private IAdminRoleService adminRoleService;

    @Autowired
    private IAdminUserRoleService adminUserRoleService;

    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    private IMonthlyOxygenDeviceService monthlyOxygenDeviceService;

    @Autowired
    private IBuyOzoneDeviceService buyOzoneDeviceService;

    @Autowired
    private IBuyOxygenDeviceService buyOxygenDeviceService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 修改用户信息 之恩呢修改基础角色
     */
    @PutMapping("/update")
    @Transactional
    @ApiOperation("修改人员信息[角色只能修改基础角色]")
    public ResponseFormat updateUser(@RequestBody @Validated UpdateUser updateUser) {

        if (!this.validNoDepartment(updateUser.getDepartmentId())) {
            return ResponseFormat.fail("部门不存在");
        }
        QueryWrapper<AdminRole> q1 = new QueryWrapper<>();
        q1.eq("id", updateUser.getRoleId());
        AdminRole adminRole = this.adminRoleService.getOne(q1);
        if (adminRole == null) {
            return ResponseFormat.fail("请选择正确的角色");
        }
        if (!adminRole.getRoleName().equals(MyRole.DISTRIBUTOR) && !adminRole.getRoleName().equals(MyRole.AGENT)) {
            return ResponseFormat.fail("只可修改为基础角色[业务员/部长]");
        }
        if (adminRole.getRoleName().equals(DefaultRole.ADMIN)) {
            return ResponseFormat.fail("不可修改成管理员");
        }
        if (updateUser.getUserId().equals(1)) {
            return ResponseFormat.fail("不可对管理员做修改");
        }
        Integer oldDepId = this.adminUserService.getDepId(updateUser.getUserId());
        AdminUser adminUser = new AdminUser(updateUser.getUserId(), updateUser.getUserName(), updateUser.getPhone(),
                this.passwordEncoder.encode(updateUser.getPassword()), updateUser.getDepartmentId());
        this.adminUserService.updateById(adminUser);

        QueryWrapper<AdminRole> q3 = new QueryWrapper<>();
        q3.in("role_name", MyRole.AGENT, MyRole.DISTRIBUTOR);
        List<Integer> roleIdList = this.adminRoleService.list(q3).stream().map(AdminRole::getId).collect(Collectors.toList());

        QueryWrapper<AdminUserRole> q2 = new QueryWrapper<>();
        //基础角色所对应的roleId
        q2.in("role_id", roleIdList);
        q2.eq("user_id", adminUser.getId());
        //删除对应的所有基础角色映射 确保了基础角色只有一个
        this.adminUserRoleService.remove(q2);
        //重新添加映射,多角色
        this.adminUserRoleService.save(new AdminUserRole(adminUser.getId(), updateUser.getRoleId()));
        /**
         * 用户部门是否有改变? 月费机器是有部门的
         */
        if (!oldDepId.equals(updateUser.getDepartmentId())) {
            //修改月费机器对应的部门
            UpdateWrapper<MonthlyfeeDevice> u1 = new UpdateWrapper<>();
            u1.set("dep_id", updateUser.getDepartmentId());
            u1.eq("admin_user_id", updateUser.getUserId());
            this.monthlyfeeDeviceService.update(u1);
            UpdateWrapper<MonthlyOxygenDevice> u2 = new UpdateWrapper<>();
            u2.set("admin_dep_id", updateUser.getDepartmentId());
            u2.eq("admin_user_id", updateUser.getUserId());
            this.monthlyOxygenDeviceService.update(u2);
            //修改购买机器对应的部门
            UpdateWrapper<BuyOzoneDevice> u3 = new UpdateWrapper<>();
            u3.set("dep_id", updateUser.getDepartmentId());
            u3.eq("admin_user_id", updateUser.getUserId());
            this.buyOzoneDeviceService.update(u3);
            UpdateWrapper<BuyOxygenDevice> u4 = new UpdateWrapper<>();
            u4.set("dep_id", updateUser.getDepartmentId());
            u4.eq("admin_user_id", updateUser.getUserId());
            this.buyOxygenDeviceService.update(u4);
        }
        this.stringRedisTemplate.delete(AdditionalController.VERSION_KEY);
        return ResponseFormat.ok("操作成功");
    }

    @PostMapping("/add")
    @ResourcesRoleMapping(resourceName = "用户控制-用户接口", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_USER})
    @ApiOperation("增加人员信息")
    public ResponseFormat addUser(@RequestBody @Validated AddUser addUser) {
        if (this.validNoRepeatUserNumber(addUser.getUserNumber())) {
            return ResponseFormat.fail("账号重复");
        }
        if (this.validNoRepeatPhone(addUser.getPhone())) {
            return ResponseFormat.failure("手机号重复");
        }

        if (!this.validOkDepartment(addUser.getDepartmentId())) {
            return ResponseFormat.fail("部门不存在");
        }

        Integer roleId = addUser.getRoleId();

        QueryWrapper<AdminRole> q1 = new QueryWrapper<>();
        q1.eq("id", roleId);
        AdminRole adminRole = this.adminRoleService.getOne(q1);
        if (adminRole == null) {
            return ResponseFormat.fail("请选择正确的角色");
        }
        if (adminRole.getRoleName().equals(DefaultRole.ADMIN)) {
            return ResponseFormat.fail("不可添加管理员");
        }
        if (!adminRole.getRoleName().equals(MyRole.DISTRIBUTOR) && !adminRole.getRoleName().equals(MyRole.AGENT)) {
            return ResponseFormat.fail("只可设置为基础角色[业务员/部长]");
        }

        AdminUser adminUser = new AdminUser(addUser.getUserName(), addUser.getUserNumber(), addUser.getDepartmentId(),
                addUser.getPhone(), this.passwordEncoder.encode(addUser.getPassword()));
        if (!this.adminUserService.save(adminUser)) {
            return ResponseFormat.fail("数据错误");
        }
        this.adminUserRoleService.save(new AdminUserRole(adminUser.getId(), addUser.getRoleId()));
        this.stringRedisTemplate.delete(AdditionalController.VERSION_KEY);
        return ResponseFormat.ok("添加成功");
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation("删除人员信息")
    public ResponseFormat deleteUserById(@PathVariable("id") Integer userId) {
        if (userId == 1) {
            return ResponseFormat.fail("不可删除管理员");
        }
        //对应管理用户名下有机器,那么就不可删除
        QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
        q1.eq("admin_user_id", userId);
        q1.last("limit 1");
        if (this.ozoneDeviceService.count(q1) != 0) {
            return ResponseFormat.fail("名下具有臭氧机,不可删除");
        }
        QueryWrapper<OxygenDevice> q2 = new QueryWrapper<>();
        q2.eq("admin_user_id", userId);
        q2.last("limit 1");
        if (this.oxygenDeviceService.count(q2) != 0) {
            return ResponseFormat.fail("名下具有氧气机,不可删除");
        }
        QueryWrapper<MonthlyfeeDevice> q3 = new QueryWrapper<>();
        q3.eq("admin_user_id", userId);
        q3.last("limit 1");
        if (this.monthlyfeeDeviceService.count(q3) != 0) {
            return ResponseFormat.fail("名下有正在进行的包月业务,不可删除");
        }
        if (!this.adminUserService.removeById(userId)) {
            return ResponseFormat.failure("删除失败");
        }
        return ResponseFormat.success();
    }

    private boolean validNoDepartment(Integer departmentId) {
        QueryWrapper<Department> q0 = new QueryWrapper<>();
        q0.eq("id", departmentId);
        Department one = this.departmentService.getOne(q0);
        return one != null;
    }

    private boolean validOkDepartment(Integer departmentId) {
        QueryWrapper<Department> q0 = new QueryWrapper<>();
        q0.eq("id", departmentId);
        Department one = this.departmentService.getOne(q0);
        return one != null;
    }

    /**
     * 返回true为重复
     *
     * @param userNumber
     * @return 是否重复
     */
    private boolean validNoRepeatUserNumber(String userNumber) {
        //如果查到有两个账号
        QueryWrapper<AdminUser> q1 = new QueryWrapper<>();
        q1.eq("user_number", userNumber);
        int count = this.adminUserService.count(q1);
        return count >= 1;
    }

    private boolean validNoRepeatPhone(String phone) {
        //如果查到有两个账号
        QueryWrapper<AdminUser> q1 = new QueryWrapper<>();
        q1.eq("user_phone", phone);
        int count = this.adminUserService.count(q1);
        return count >= 1;
    }

}
